# Milestone 5: Developer Portal Frontend **Status**: Decided **Goal**: Web interface for developer account and app management. ## Decision **htmx + Go Templates** for server-rendered UI from the single Go container: ``` Rendering: Go html/template Interactivity: htmx (partial page updates) Styling: Tailwind CSS (compiled at build time) Charts: Chart.js (lightweight) Icons: Heroicons or Lucide Build: Embed static assets in Go binary ``` ### Rationale 1. **Single container** - No separate Node.js server needed 2. **Server-rendered** - All HTML generated by Go templates 3. **htmx for interactivity** - AJAX without JavaScript framework 4. **Embedded assets** - CSS/JS bundled into Go binary via `embed` 5. **Simple deployment** - Just the Go binary, nothing else 6. **Low resource usage** - Perfect for Synology NAS ### Architecture ``` ┌─────────────────────────────────────────┐ │ mosis-portal container │ │ ┌────────────────────────────────────┐ │ │ │ Go binary │ │ │ │ ├── Chi router │ │ │ │ ├── html/template rendering │ │ │ │ ├── Embedded static assets │ │ │ │ │ ├── tailwind.css (built) │ │ │ │ │ ├── htmx.min.js │ │ │ │ │ └── chart.min.js │ │ │ │ └── SQLite database │ │ │ └────────────────────────────────────┘ │ └─────────────────────────────────────────┘ ``` --- ## Overview The developer portal is the primary interface for developers to manage their accounts, create apps, submit versions, and view analytics. --- ## Pages Required ### Public Pages | Page | URL | Purpose | |------|-----|---------| | Landing | `/` | Marketing, sign up CTA | | Sign In | `/login` | OAuth + password login | | Sign Up | `/register` | Create account | | Docs | `/docs/*` | Documentation (separate site?) | ### Authenticated Pages | Page | URL | Purpose | |------|-----|---------| | Dashboard | `/dashboard` | App list, quick stats | | App Details | `/apps/:id` | Single app overview | | App Settings | `/apps/:id/settings` | Edit app metadata | | App Versions | `/apps/:id/versions` | Version history | | Submit Version | `/apps/:id/versions/new` | Upload new version | | App Analytics | `/apps/:id/analytics` | Telemetry dashboard | | Create App | `/apps/new` | New app wizard | | API Keys | `/settings/keys` | Manage API keys | | Signing Keys | `/settings/signing` | Manage signing keys | | Profile | `/settings/profile` | Account settings | --- ## Wireframes ### Dashboard ``` ┌─────────────────────────────────────────────────────────────┐ │ [Logo] Dashboard Apps Docs Settings [Avatar ▼] │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Welcome back, Developer! │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Total Apps │ │ Downloads │ │ Active Users│ │ │ │ 12 │ │ 45,230 │ │ 1,234 │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ Your Apps [+ New App] │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ [Icon] My Calculator v1.2.0 Published 1.2K ↓ │ │ │ │ [Icon] Notes App v2.0.1 Published 5.4K ↓ │ │ │ │ [Icon] Weather Widget v0.9.0 In Review --- │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### App Details ``` ┌─────────────────────────────────────────────────────────────┐ │ ← Back to Apps │ ├─────────────────────────────────────────────────────────────┤ │ │ │ [Icon] My Calculator │ │ com.developer.calculator │ │ ● Published │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Overview │ │ Versions │ │Analytics │ │ Settings │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ Latest Version: 1.2.0 [Submit New Version] │ │ Published: Jan 15, 2024 │ │ Downloads: 1,234 │ │ │ │ ┌────────────────────────────────────────┐ │ │ │ Downloads over time │ │ │ │ [Chart: line graph] │ │ │ └────────────────────────────────────────┘ │ │ │ │ Recent Crashes [View All →] │ │ • attempt to index nil (v1.2.0) - 23 reports │ │ • memory limit exceeded (v1.1.0) - 5 reports │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### Submit Version ``` ┌─────────────────────────────────────────────────────────────┐ │ Submit New Version - My Calculator │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Step 2 of 3: Upload Package │ │ ○ Details ● Upload ○ Review │ │ │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ │ │ │ │ ┌─────────┐ │ │ │ │ │ .mosis │ Drop your package here │ │ │ │ │ 📦 │ or click to browse │ │ │ │ └─────────┘ │ │ │ │ │ │ │ │ Max size: 50 MB │ │ │ │ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ ✓ Package validated │ │ ✓ Signature verified │ │ ✓ Permissions: storage, network │ │ │ │ [Back] [Continue to Review] │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Tech Stack Options ### Option A: Next.js 14 ``` Framework: Next.js 14 (App Router) UI: shadcn/ui + Tailwind CSS State: React Query + Zustand Forms: React Hook Form + Zod Charts: Recharts or Tremor Auth: NextAuth.js ``` | Pros | Cons | |------|------| | SSR for SEO landing page | Complexity | | Great developer experience | React knowledge required | | Full-stack capability | Heavier bundle | | Large ecosystem | | ### Option B: SvelteKit ``` Framework: SvelteKit UI: Skeleton UI or custom State: Svelte stores Forms: Superforms Charts: Chart.js or LayerCake Auth: Lucia ``` | Pros | Cons | |------|------| | Fast, small bundles | Smaller ecosystem | | Simple state management | Fewer UI libraries | | Great DX | Less hiring pool | ### Option C: Astro + React Islands ``` Framework: Astro UI: React components (islands) State: Nanostores Forms: React Hook Form Charts: Recharts Auth: Custom ``` | Pros | Cons | |------|------| | Ultra-fast static pages | More setup | | Partial hydration | Newer approach | | Use React where needed | Less documented patterns | ### Option D: htmx + Go Templates ``` Framework: Go templates + htmx UI: Tailwind CSS State: Server-side Forms: Native HTML Charts: Chart.js Auth: Server sessions ``` | Pros | Cons | |------|------| | Simple, fast | Limited interactivity | | No JS framework | Less polished UX | | Server-rendered | Complex UI harder | --- ## UI Component Library ### Option A: shadcn/ui ``` Base: Radix UI primitives Styling: Tailwind CSS Approach: Copy-paste components ``` | Pros | Cons | |------|------| | High quality | React only | | Full control | Manual updates | | Accessible | | ### Option B: Tailwind UI ``` Base: Headless UI Styling: Tailwind CSS Approach: Copy-paste templates ``` | Pros | Cons | |------|------| | Beautiful designs | Paid ($299) | | Production-ready | Templates, not components | ### Option C: Mantine ``` Base: Custom components Styling: CSS-in-JS or CSS Approach: npm package ``` | Pros | Cons | |------|------| | Complete solution | Opinionated | | Many components | Larger bundle | | Good docs | | --- ## Key Features (htmx Implementation) ### File Upload with Progress ```html
Uploading...
``` ### Dynamic App List ```html
{{range .Apps}}
{{.Name}}

{{.Name}}

{{.Status}} View →
{{end}}
``` ### Form with Validation ```html
``` ### Analytics Chart ```html
``` --- ## Go Template Structure ### Base Layout ```go // templates/layouts/base.html {{define "base"}} {{.Title}} - Mosis Developer Portal {{template "navbar" .}}
{{template "content" .}}
{{end}} ``` ### Page Template ```go // templates/pages/dashboard.html {{define "content"}}

Dashboard

{{template "stat-card" dict "Label" "Total Apps" "Value" .Stats.TotalApps}} {{template "stat-card" dict "Label" "Downloads" "Value" .Stats.Downloads}} {{template "stat-card" dict "Label" "Active Users" "Value" .Stats.ActiveUsers}}

Your Apps

+ New App
Loading...
{{end}} ``` --- ## Authentication Flow ### Login Page (Go Template) ```html {{define "content"}}

Sign in to Mosis

{{end}} ``` ### Auth Middleware (Go) ```go // middleware/auth.go func RequireAuth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { session, err := sessionStore.Get(r, "session") if err != nil || session.Values["developer_id"] == nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } next.ServeHTTP(w, r) }) } // Usage in router r.Group(func(r chi.Router) { r.Use(RequireAuth) r.Get("/dashboard", handlers.Dashboard) r.Get("/apps", handlers.AppList) r.Get("/apps/{id}", handlers.AppDetail) }) ``` --- ## Responsive Design ### Breakpoints | Size | Width | Target | |------|-------|--------| | sm | 640px | Mobile landscape | | md | 768px | Tablet | | lg | 1024px | Desktop | | xl | 1280px | Large desktop | ### Mobile Navigation ```tsx // Hamburger menu for mobile ``` --- ## Accessibility ### Requirements - [ ] Keyboard navigation - [ ] Screen reader support - [ ] Color contrast (WCAG AA) - [ ] Focus indicators - [ ] Alt text for images - [ ] Form labels - [ ] Error announcements ### Testing ```bash # Lighthouse audit npx lighthouse http://localhost:3000 --view # axe-core npm install @axe-core/react ``` --- ## Deliverables - [x] Framework selection (htmx + Go Templates) - [x] UI component library selection (Tailwind CSS + Chart.js) - [ ] Design system (colors, typography) - [x] Page wireframes (see above) - [x] Authentication flow (server sessions + OAuth) - [ ] Dashboard implementation - [ ] App management pages - [ ] Version submission flow - [ ] Settings pages - [ ] Responsive design - [ ] Accessibility audit --- ## Open Questions 1. ~~Dark mode support?~~ → Defer to post-MVP (Tailwind makes it easy to add later) 2. ~~Internationalization (i18n)?~~ → English only for MVP 3. ~~Custom domain for docs vs integrated?~~ → Integrated into same Go server at /docs 4. Email notifications UI? → Consider for v1.1 --- ## References - [shadcn/ui](https://ui.shadcn.com/) - [Next.js App Router](https://nextjs.org/docs/app) - [Tailwind CSS](https://tailwindcss.com/) - [React Query](https://tanstack.com/query/latest)