2.1 KiB
2.1 KiB
Architecture
RenewCMS is a Go HTTP API and a Vue 3 SPA, shipped as a single binary.
Backend layering
Dependencies point inward:
api/ ──▶ internal/infrastructure/useCases ──▶ internal/domain ◀── internal/infrastructure/{persistence,mailer}
| Layer | Location | Rules |
|---|---|---|
| Domain | internal/domain/<name>/ |
Entities, Err… sentinel errors, Repository interfaces. Imports only the stdlib and other domain packages, with no GORM tags. |
| Use cases | internal/infrastructure/useCases/ |
Application logic. Depends only on domain interfaces, never on persistence, mailer, GORM or net/http. |
| Adapters | internal/infrastructure/persistence/{models,mappers,repositories}, internal/infrastructure/mailer |
Implement a domain Repository (assert with var _ domain.Repository = &X{}). GORM structs stay in models and are converted by mappers. |
| Delivery | api/handlers/<name>/, api/router.go |
HTTP handlers receive use cases through NewHandler(...). They never import persistence, mailer or GORM. |
| Composition root | api/dependecyInjection.go |
The only place that opens the DB, builds repositories and use cases, and lists models for AutoMigrate. |
| Entry point | cmd/server/main.go |
Env/config, HTTP server, graceful shutdown. |
Nothing under internal/ imports api/.
Frontend ↔ backend
web/ (Vue, Vite)
│ task build:web (vue-tsc + vite build)
▼
internal/infrastructure/assets/dist/ gitignored build output
│ //go:embed all:dist (assets_embed.go, default build)
▼
bin/renewcms ── /v1/* API
── /healthz
── /* SPA (api/handlers/frontend), index.html fallback
- Production: a single origin. The SPA calls the API with relative URLs, so the JWT cookie works without CORS. Files under
assets/are content-hashed by Vite and cached for a year.index.htmlis never cached. - Development: built with
-tags nofrontend(assets_stub.go,assets.Dist == nil). Vite serves the SPA on :5173 and proxies/v1to the API on :8080. See development.md.