Adds multi-tenant organisation support inside the existing finance namespace.
Users can create organisations, invite others via a copy-paste token link,
and manage teams/members with RBAC (admin, finance, member, viewer).
Fiscal year lifecycle is gated: activation requires all planned events to
be approved first. All org data lives in `org_`-prefixed MongoDB collections.
New files:
- models_org.go — domain types (Org, OrgTeam, OrgMember, OrgInvite,
FiscalYear, OrgEvent, BudgetLine, EventComment,
TxRequest with full StatusLog audit trail, etc.)
- store_org.go — MongoDB store methods for all org collections
- handler_org.go — HTTP handlers + RegisterOrgRoutes(); join invite
route lives at /join/{token} to avoid ServeMux
conflict with /orgs/{slug}/... wildcard routes
- templates/org_*.html — list, create, home, teams, members, invite, join
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
34 lines
1.4 KiB
HTML
34 lines
1.4 KiB
HTML
{{define "content"}}
|
|
{{$d := .}}
|
|
|
|
<div style="max-width:440px; margin:0 auto; padding-top:32px;">
|
|
<div class="card" style="text-align:center;">
|
|
<div style="font-size:48px; margin-bottom:16px;">🏢</div>
|
|
<h1 style="font-size:22px; margin-bottom:8px;">You've been invited</h1>
|
|
<p style="color:var(--text2); font-size:14px; margin-bottom:24px;">
|
|
Join <strong style="color:var(--text);">{{$d.Org.Name}}</strong> as
|
|
<strong style="color:var(--accent2);">{{$d.Invite.Role}}</strong>
|
|
</p>
|
|
|
|
{{if $d.Invite.TeamIDs}}
|
|
<div style="margin-bottom:20px; padding:12px 16px; background:var(--bg3); border-radius:var(--radius-sm); text-align:left;">
|
|
<div style="font-size:11px; font-weight:700; letter-spacing:.06em; color:var(--text3); margin-bottom:6px;">ASSIGNED TEAMS</div>
|
|
{{range $d.Invite.TeamIDs}}
|
|
<div style="font-size:13px; color:var(--text2); padding:2px 0;">· {{.}}</div>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
|
|
<p style="font-size:12px; color:var(--text3); margin-bottom:24px;">
|
|
Joining as <strong style="color:var(--text);">{{$d.Email}}</strong>.<br>
|
|
This invite expires {{dateShort $d.Invite.ExpiresAt}}.
|
|
</p>
|
|
|
|
<form method="post" action="/join/{{$d.Invite.Token}}">
|
|
<button type="submit" class="btn btn-primary" style="width:100%; margin-bottom:10px;">Accept & join</button>
|
|
</form>
|
|
<a href="/" style="font-size:13px; color:var(--text3);">Decline</a>
|
|
</div>
|
|
</div>
|
|
{{end}}
|