Files
mygo/docs/architecture.md

3.6 KiB

Architecture

Layered Design

Handler (Gin handlers)          ← translates HTTP ↔ Service calls
    ↓
Service (business logic)        ← orchestrates, authorizes, validates
    ↓                        ↓
Repository (GORM data access)   Storage (file I/O)
    ↓                        ↓
[SQLite / PostgreSQL]        [Local FS / S3]

Rules:

  • Handler has no business logic — parse request, call service, write response.
  • Service has no HTTP awareness — operates on domain models and interfaces.
  • Repository abstracts the database; Storage abstracts where bytes live.
  • internal/server is the composition root — wires all dependencies together.

Package Map

Layer Package Purpose Status
CLI cmd Cobra root command 🛠 WIP
cmd/serve.go mygo serve — wire deps, start HTTP
cmd/config.go mygo config — config subcommand 🛠 WIP
cmd/status.go mygo status — health check 🛠 WIP
Config internal/config Viper load (YAML + env + flags), typed Duration config via built-in decode hook
App internal/app Runtime dependency container and build metadata 🛠 WIP
HTTP internal/server Gin router init, route registration (public/protected split), graceful shutdown
internal/handler HTTP handlers (auth, file, admin, webdav...) 🛠 WIP
internal/middleware Gin middleware (logger, jwt, cors, auth) 🛠 WIP
Business internal/service Business logic: AuthService (register, login, refresh, logout, passkey CRUD)
internal/model Domain types (User, File, Credential, Session), error codes
Data internal/repository Repository interfaces + GORM implementations (User, Session, File, Credential)
internal/storage Storage backend interface + local disk impl 🛠 WIP
Util internal/auth JWT sign/verify (HS256), token type discrimination (access/refresh), password hashing (bcrypt), app passkey tokens
internal/api Unified JSON error response helpers

API Routes (v0)

GET /api/v1/version

POST /api/v1/auth/register
POST /api/v1/auth/login
POST /api/v1/auth/refresh
POST /api/v1/auth/logout

GET    /api/v1/account
GET    /api/v1/account/passkeys
POST   /api/v1/account/passkeys
DELETE /api/v1/account/passkeys/:id

GET    /api/v1/files
POST   /api/v1/files
GET    /api/v1/files/:id
GET    /api/v1/files/:id/content
PUT    /api/v1/files/:id
DELETE /api/v1/files/:id

GET    /api/v1/admin/users
GET    /api/v1/admin/users/:id
PUT    /api/v1/admin/users/:id
DELETE /api/v1/admin/users/:id

Middleware Chain

Applied globally by gin.Default(): logger → recovery

Planned globally: cors

Applied to protected groups: auth (JWT validation, inject user into gin.Context)

Server Responsibilities

  • cmd/serve.go loads config, calls app.Bootstrap to initialize DB + services, builds the router, and starts the HTTP server.
  • app.WebApp carries runtime dependencies and build metadata needed to assemble handlers.
  • internal/server owns Gin router setup (router.go), route registration split into routes_public.go (public auth) and routes_protected.go (JWT-protected account).
  • Each route group creates its own handler instance: routes_public.go creates AuthHandler, routes_protected.go creates AccountHandler — no shared handler state between public and protected routes.
  • RunWithGracefulShutdown stops accepting new requests on termination and gives in-flight requests time to finish.