Count hand-valued assets into the wealth figure

A wealth figure that ignores the house is not a wealth figure. Assets
without a market feed - a house, a car, a private loan - are now added
by hand on the Wealth page with a stated value, a currency and the day
the estimate was made; a negative value records a liability. They are
registry entities in assets.finance like everything else, join the
per-currency totals immediately, and a currency held only in an asset
earns its own line.
This commit is contained in:
Lars Nolden
2026-09-14 09:29:19 +02:00
parent a1480af74d
commit 77f4ea5655
15 changed files with 564 additions and 29 deletions
+12
View File
@@ -45,6 +45,7 @@ func New(a *app.App, assets fs.FS, publicURL string) (http.Handler, error) {
s.mux.HandleFunc("POST /api/tags", s.tag)
s.mux.HandleFunc("POST /api/merchants", s.merchant)
s.mux.HandleFunc("POST /api/instruments", s.instrument)
s.mux.HandleFunc("POST /api/assets", s.asset)
s.mux.HandleFunc("POST /api/transactions/{id}/transfer", s.transfer)
s.mux.HandleFunc("POST /api/transactions/{id}", s.transaction)
s.mux.HandleFunc("POST /api/manage", s.manage)
@@ -294,6 +295,17 @@ func (s *Server) instrument(w http.ResponseWriter, r *http.Request) {
v, e := s.app.Mutate(r.Context(), b.Revision, func(d *domain.Dataset) error { return app.SaveInstrument(d, b.Instrument) })
respond(w, v, e)
}
func (s *Server) asset(w http.ResponseWriter, r *http.Request) {
var b struct {
Revision string `json:"revision"`
Asset domain.Asset `json:"asset"`
}
if !decode(w, r, &b) {
return
}
v, e := s.app.Mutate(r.Context(), b.Revision, func(d *domain.Dataset) error { return app.SaveAsset(d, b.Asset) })
respond(w, v, e)
}
// transfer links or unlinks one transaction's own-account counterpart. It is a
// separate endpoint because both sides change together: the transaction editor