Commit Graph
46 Commits
Author SHA1 Message Date
cgalo5758 9b96e9c9e9 Rework operator IA and unify UI vocabulary
- Restructure operator sidebar into a flat task list with indented
  children; fold plan topology into plan ladders
- Expand member catalog non-plan section to all published non-tier
  products; require recurring Stripe-mapped prices for purchase
- Add operator domains placements and terminal-claims ledger; redirect
  /domains to the FedWiki Sites Domains anchor
- Apply canonical vocabulary and chrome/form conventions; migrate seeded
  FedWiki Sites display name
2026-08-23 17:12:42 -05:00
cgalo5758 8e3c68c6be Make UI surfaces honestly reflect system state
- Add deployment-name branding to titles, mastheads, and OG tags
- Share one grant delivery-state query with lineage across grants
  surfaces
- Show pool status/usage, org owners, and config readiness
- Make billing views projection-aware with recency and sync vocabulary
- Guard FedWiki creation without domains and render route-aware 404s
2026-08-23 01:45:52 -05:00
cgalo5758 ad7a219adf Enforce schema and boot invariants
Enforce 10j's verified gaps (schema-hardening change):

- Migration 00010: partial unique indexes for one default pool and one
  primary assignment per workspace, plus CHECKs pinning
  pool/provider/subscription vocabularies and provider lifecycle
  timestamps.
- Workspace creation shares a transactional provisioning function;
  extension validates its target pool; last-tier deletion of a defaulted
  ladder is guarded; signup completes plan-less on a broken ladder.
- Boot asserts integration slug parity and validates declared config
  enums; Stripe invoice amounts are range-checked; domain cancellation
  runs a final evidence probe; rule authoring is additive-only.
2026-08-22 18:02:46 -05:00
cgalo5758 6dbce6140f Type the ConfigSpec seam and move the connect target to core
Register bool and duration ConfigSpec keys from the Default's type, move
fedwiki's four sync knobs and discourse's two into their integrations'
ConfigSpecs, and replace core's read of fedwiki-custom-domain-target
with a core domains-connect-target key resolved once and threaded
through server and worker config.

Generate init's optional-integration scaffold sections from each
registered ConfigSpec instead of the hand-maintained list, and reword
the Temporal boot warning generically.

Archives the integration-config-parity change; status bookkeeping and
the verify-skill doc follow with the test-stack commit.
2026-08-01 04:13:48 -05:00
cgalo5758 8e7e0dd04d Harden container, OIDC auth, and error handling
Run Docker runtime stage as non-root user app (UID 65532).

Add styled full-page 404/500 error rendering for navigation requests
while preserving plain-text responses for HTMX partials.

Reuse recent unconsumed OIDC login state to avoid state mismatch on
parallel login hits, and merge resource_access in role extraction.

Re-level template headings, add autocomplete tokens, and resolve
catalog resource display names.

Self-label test-stack secrets and document CSRF secret rotation.
2026-07-31 23:27:15 -05:00
cgalo5758 ce3668d59e Refine operator overview metrics and styling
Replace domain claims with open invoices, show monthly recurring
revenue,
count team organizations, and add more informative trend captions.

Use standard bordered cards and add a README screenshot with reversible
sample-data tooling.
2026-07-27 02:44:55 -05:00
cgalo5758 0affda70bd Centralize the external-claim entitlement gate in the registry
Registry.ClaimExternal now enforces the plan gate itself via an injected
domains.ExternalClaimGate (pre-lock, typed refusals), so every entry
point — and any future consumer — inherits it from the allocation API.
One constructor in internal/server builds the gate from the entitlements
querier and connect target; it is injected into the member-facing
registry constructions in server.go and fedwiki.go and drives affordance
rendering on both surfaces. The duplicated helpers and resource-key
constants in fedwiki web and member_domains are gone; fedwiki no longer
reads entitlement tables for this gate at all.

Archives the change with the domains-registry spec delta (enforcement
location is now requirement-level: registry-inherited, surfaces derive).
Closes the entitlement-gate placement debt in issues.md; files the
separately-discovered operator force-release dead-end affordance bug
that a placed claim exposed in the domains walkthrough.
2026-07-26 03:33:16 -05:00
cgalo5758 d3b222a446 Dissolve the member domains surface into point-of-use
Domains leaves the member nav everywhere; GET /domains 302s to the
dashboard and domains.html is deleted. Claims are managed where they are
used: the fedwiki sites card embeds the core claims partial, a
server-conditional dashboard notice carries pending verifications (the
durable re-entry now that the page is gone), and the member_domains
partials retarget to 'closest .domains-surface' so multiple hosts coexist
on one page. Adding an external domain starts only from the create form;
the fedwiki banner slims to verified-unplaced one-click creates, since
the notice and embedded section own the pending state.

Verified at the surface end-to-end (stack + Chrome): nav absence,
redirect, notice lifecycle through claim-cancel, and cross-host swap
isolation with two claim views open. Archives the change with spec
deltas synced (domains-registry point-of-use rewrite, fedwiki-sites and
member-dashboard additions); files the entitlement-gate placement debt
in issues.md; adds the repo verify skill.
2026-07-26 03:10:23 -05:00
cgalo5758 4cec3868d4 Rebuild the operator landing as a real overview
Replace the bare landing panel with a four-region overview: lookup, an
"At a glance" tile row, a unified activity timeline, and a System rail.

The tiles are chosen so each earns its place and each drills into a real
operator section, which makes the row double as navigation for an
operator who arrived without a destination. People carries no link
because there is no persons browse route by design -- persons are reached
by lookup. Grants and provisions share one tile: the headline counts
grants and the caption names the active provisions it was joined against,
so the ledger-versus-delivery distinction is visible on the page instead
of only in the SQL.

Every count degrades independently, like the activity feed already did. A
failed count renders an em dash and says so; it never renders zero, since
an operator reading "0 organizations" off a broken query would draw
exactly the wrong conclusion. This is the surface people reach for when
something is already wrong, so it has to render under partial failure.

The System rail reports every registered provider, not just the
provisioning ones the sidebar lists, and splits the outbox by what an
operator would do about each bucket -- only dead-lettered work, which has
exhausted its retries, gets the alarm.

Headings run H1 to H3 with no skipped levels; the H1-to-H6 pattern of the
older operator pages is deliberately not copied. The stat-tile hover and
focus affordance lives in app.css because Bootstrap cards are containers,
not controls, and it is suppressed under reduced-motion. No new JS, no
inline script, handler or style attribute.

The shell's title and brand no longer name a specific deployment: this is
general-purpose OSS and the operator surface is the first page a stranger
evaluating the project sees.

Covered by operator_overview_render_test.go, which renders the template
without a database and guards the outline, the CSP constraints, the
brand neutrality, the empty states, and the em-dash-not-zero rule.
2026-07-25 15:44:36 -05:00
cgalo5758 c85ac6acdc Add domain claim lifecycle safeguards
Make claim windows and workspace caps configurable, and enforce
initiation
and abandonment budgets without penalizing DNS evidence or system
failures.
Add operator visibility into live claims and default verification to 24
hours.
2026-07-25 00:40:24 -05:00
cgalo5758 8d05934e93 Add domains registry with claims and placements
Domain names become an allocatable resource with one authority. A new
core module (schema `domains`, own migration stream between core and the
integrations) owns claims — a DNS node plus its whole subtree, mutually
disjoint: operator shared-domain roots, member claims carved from them,
and bring-your-own names proven by TXT verification — and placements,
which bind a name inside a claim to a provider slug and resource ref.

Verification moves to the claim and decouples from creation. A member
proves control of a domain once; afterwards every name inside it places
instantly, wildcard-CNAME friendly, with no further DNS work. The claim
workflow activates the claim and stops — it no longer creates a site —
so the sites list offers a one-click create once a domain verifies.

/domains/ask answers from placements and is registered by core rather
than the FedWiki adapter; its HTTP contract is unchanged. A configured
`domains-ask-fallback-url` forwards names the registry does not know to
a legacy answerer, the strangler seam wiki.cafe's migration needs; a
name the registry knows but has archived is refused locally.

FedWiki's create saga reserves the name before the farm call, carrying a
workflow-minted site id so retries are idempotent, and compensates on
failure. Sync places only names it owns, never stealing a member's;
lifecycle transitions and the retention purge maintain servability. An
unconditional boot pass seeds operator roots, releases orphaned
placements, and adopts pre-existing sites — grandfathering member-owned
external domains shortest-name-first, and skipping name policy, so a
live single-letter site cannot lose its certificate.

Members manage domains at /domains: claims with verification status, DNS
records including an optional wildcard row, check-now, cancel, release.
Name policy (reserved, blocked, premium, plus a single-letter guard) is
operator data; refusals collapse to a plain "unavailable" so the console
never becomes an oracle for who holds what.

BREAKING (pre-release): `fedwiki.custom_domain_verifications` and
`sites.is_custom_domain` are dropped, the flag now derived from the
placement's claim kind; resource key `fedwiki_custom_domains` migrates
to the platform-owned `external_domain_claims`; running
verify-custom-domain workflows must be terminated before deploy.
2026-07-24 21:25:40 -05:00
cgalo5758 259c935981 Unify operator integration management
List every provider kind with direct settings and admin links, move
FedWiki
under the integrations route, and add in-shell operator 404s.

Report sync health from Temporal schedule executions and clear one-shot
settings feedback parameters after display.
2026-07-23 00:14:21 -05:00
cgalo5758 296236a721 Add operator-managed integration settings
Persist non-secret ConfigSpec overrides in core and apply them at boot
ahead of environment values and defaults. Validate typed and enum
values,
show pending restart state, and remove Stripe's unused provider config
table.
2026-07-22 22:17:58 -05:00
cgalo5758 2816c1e0b0 Make member dashboard registry-driven
Render generic HTMX card shells from integration declarations. Move the
FedWiki UI into its partial, add Discourse forum status, and label
member
entitlements with provider attribution.
2026-07-21 22:50:52 -05:00
cgalo5758 a94ff08336 Add Discourse integration
Deliver forum posting entitlements through managed group membership with
identity linkage, periodic reconciliation, webhook handling, and an
operator mapping surface.

Include fake and live test environments, setup documentation,
migrations,
and end-to-end coverage.
2026-07-20 19:49:34 -07:00
cgalo5758 1a8e13f880 Extract integrations into registered trees
Add an explicit registry with capability hooks for migrations, routes,
workflows, config, and UI assets. Move FedWiki fully and Stripe's
separable
store, workflow, and webhook pieces under internal/integrations.

Drive startup wiring from declarations, including config validation,
secret
file pairs, CSRF exemptions, UI composition, and workflow startup. Move
integration DB roles and grants into their owning migration streams, and
route outbox writes through a shared enqueue helper.
2026-07-06 11:01:07 -05:00
cgalo5758 02bab9471b Complete purchasability sync handling
Gate Stripe readiness on real credentials, surface dead-lettered syncs
as
failed with retry, and add header-safe toast JSON encoding.

Switch the test Keycloak realm references to `test` and document the
OpenSpec change.
2026-07-02 03:10:33 -05:00
cgalo5758 3e1290e1d0 Gate FedWiki active rotations by cooldown
Add a configurable cooldown window and route restores, reactivations,
and swaps through the same rotation check to close the archive/restore
bypass while preserving headroom and no-reserve activations.
2026-06-24 03:09:26 -05:00
cgalo5758 9b13c22d46 fix: operator landing page missing registry-driven Integration nav
The operator sidebar's Integration group is registry-driven
(OperatorPageData.IntegrationProviders, loaded from integration.providers).
Every operator MPA page builds its page data via buildOperatorPageData, which
populates that slice — except the landing/overview surface, rendered by the
separate OperatorHandler.renderLanding, which built OperatorPageData inline and
never set IntegrationProviders (OperatorHandler had no DB access at all). So
FedWiki showed in the sidebar on every operator page except the overview.

Extract loadIntegrationProvidersNav as a shared free function, give
OperatorHandler a Database field (wired in server.go), and have renderLanding
load the same nav and set CurrentPath. Latent since the M9
provider-extension-contract change made the Integration nav registry-driven.
2026-06-23 16:37:37 -05:00
cgalo5758 ee8568e28c feat(billing): reconcile Stripe subscriptions from the API
Replace the order-dependent, payload-trusting webhook fulfillment with a single
idempotent ReconcileSubscription (internal/fulfillment) that refetches
authoritative subscription state from the Stripe API and converges core records
and pool entitlements via the plan-transitions primitive. checkout.session.completed
and customer.subscription.* become thin triggers; the post-checkout return path
reconciles eagerly. This fixes paid upgrades provisioning zero entitlement, caused
by reading the empty line_items the webhook payload never carries.

- internal/fulfillment: ReconcileSubscription + ReconcileLatestSubscriptionForCustomer,
  advisory-locked, convergent/idempotent, with unit + DB-gated integration tests
- internal/stripetest: in-process stripe.Backend mock for offline reconcile tests
- thin webhook handlers; eager reconcile on /?checkout=success (best-effort)
- stripe.Key set process-wide before the Temporal worker starts (cmd/start.go)
- OpenSpec change stripe-fulfillment-reconcile; archive completed member-upgrade-flow
  now that its paid-upgrade demonstration (§5.3) is satisfied
2026-05-23 21:47:38 -05:00
cgalo5758 17a9ad412d Enable member upgrade flow via HTMX Checkout 2026-05-23 15:47:10 -05:00
cgalo5758 6345197ec1 Add member billing invoice history
Add /billing page and HTMX partials (list + detail) for invoice
history. Introduce MemberInvoicesHandler, wire routes, add templates,
unit and DB scoping tests, and openspec docs. Update nav links.
2026-05-22 02:46:05 -05:00
cgalo5758 46f727fb21 Use #operator-body as HTMX swap target
Add per-field validation UI (is-invalid + invalid-feedback) and
propagate FieldErrors in view models. Replace HTMX "Back" buttons with
regular links. Initialize web.New() for collecting form errors. Register
a /partials/ 404 handler to prevent accidental dashboard swaps during
HTMX partial requests.
2026-05-17 14:34:05 -05:00
cgalo5758 38b703c1cf Add recent activity queries and operator timeline 2026-05-16 04:13:05 -05:00
cgalo5758 2860f27d71 Add MPA handlers and body template dispatch
Introduce a renderBody template func to dispatch dynamic body partials
from operator.html (real implementation in NewOperatorPartialsHandler).
Add GetOrganizationsPage and GetOrganizationDetailPage to render MPA
pages by setting BodyTemplate/BodyData and ActiveCapability on the
OperatorPageData. Refactor enrollment hydration into
loadOrgEnrollmentData,
update templates to use /operator/organizations links and target
2026-05-15 23:47:41 -05:00
cgalo5758 8f6a93f74d Add operator enrollment UI and plan docs
Introduce operator enrollment partials and handlers that route plan-tier
granting and revocation through entitlements.Transition(). Add
member-facing
tier labels, plan architecture and grant-plan-safety documentation, plus
unit and e2e tests. Also add small querier helpers and wire Temporal
client
hooks for trial expiration scheduling.
2026-04-24 12:28:00 -05:00
cgalo5758 1a89bbd292 Products page done. 2026-04-11 20:40:36 -05:00
cgalo5758 be91b73dbd Stripe Operator UI 2026-04-06 03:15:20 -05:00
cgalo5758 7ef1d32529 Stripe subcription creation 2026-04-05 02:00:07 -05:00
cgalo5758 3aad9268df Stripe Billing Plumbing 2026-04-03 19:25:24 -05:00
cgalo5758 675a4d93a3 Buffer template rendering and fix FedWiki sync
Introduce SafeTemplates.Render to execute templates into a buffer and
prevent partial HTML on errors. Replace direct ExecuteTemplate calls in
partial handlers and add a make lint-templates target to catch bypasses.
Update operator sites template/view model to use OwnerOrgName. Guard the
FedWiki sync by skipping inserts when DefaultWorkspaceID is empty and
scope deletes to the configured default workspace only.
2026-03-29 04:58:02 -05:00
cgalo5758 47a75e0873 Add products, entitlement sets, and workspace support
- Add SQL queries and generated methods for Create/List/Update products
- Add CountWorkspacesByOrgID and ListResourceKeys querier methods
- Register workspace partials and operator routes for products and sets
- Add workspace UI section and operator tabs; tweak grant/site forms
- Replace isValidDNSLabel with validateDNSLabel for site validation
2026-03-27 10:55:03 -05:00
cgalo5758 6330ae7a42 Grants management! 2026-03-24 17:35:14 -05:00
cgalo5758 f737dd0314 Identity and organization modules. 2026-03-23 17:28:14 -05:00
cgalo5758 5b7c2c6d2d Use session key constants and typed accessors. Fixes issues with
previous commit.
2026-02-02 22:37:06 -06:00
cgalo5758 ddb206f7ac Use Valkey for server-side session storage with SCS. 2026-02-02 22:19:22 -06:00
cgalo5758 1860ec6068 feat: Implement operator dashboard with user, site, and payment management views. 2026-01-17 15:56:22 -06:00
cgalo5758 b1282c7488 Make site ownership work correctly for fucks sake. 2026-01-01 22:07:11 -06:00
cgalo5758 0751e71f3c Add error handling for HTMX requests with toast notifications 2025-12-28 16:16:37 -06:00
cgalo5758 74002e424f Rough FedWiki Site management through temporal workflows! 2025-12-18 01:05:55 -06:00
cgalo5758 a7d3822f94 Implement database integration with SQLite and refactor user handling for OIDC authentication 2025-06-02 19:35:11 -05:00
cgalo5758 ed00e1150f Refactor OIDC configuration keys for consistency and clarity 2025-05-18 17:48:51 -05:00
cgalo5758 0c6b1cd6b5 Dynamic user data for dashboard and a link to manage their IDP account! 2025-05-16 02:00:02 -05:00
cgalo5758 c0bc02fed5 Use embedded filesystems properly. 2025-05-13 22:49:36 -05:00
cgalo5758 27eb2e5f12 Server serves default content using go embed. Also add favicons/ 2025-05-13 00:52:52 -05:00
cgalo5758 e5e9efd9b3 Refactor start.go to move server logic to internal server.go 2025-05-11 04:32:54 -05:00