Skip to content

feat: dashboard backend (v0.47 phase 3a) - #25

Merged
Ferousco-dev merged 1 commit into
mainfrom
Feranmi_works
Sep 25, 2026
Merged

Ferousco-dev merged 1 commit into
mainfrom
Feranmi_works

Conversation

@Ferousco-dev

@Ferousco-dev Ferousco-dev commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • GET /v1/me / PATCH /v1/me — human profile (name, avatar_url)
  • GET /v1/orgs/{id} (any member) / PATCH /v1/orgs/{id} (owner) — org detail/settings
  • GET /v1/orgs/{id}/members (any member) / DELETE /v1/orgs/{id}/members/{humanId} (owner) — member management, with a row-locked last-owner invariant (concurrent mutual-removal race-tested)
  • GET /v1/orgs/{id}/invites / DELETE /v1/orgs/{id}/invites/{inviteId} (owner) — pending invite management, idempotent revoke
  • GET /v1/orgs/{id}/analytics/overview / /timeseries (any member) — human-JWT-scoped wrapper reusing the existing analytics handlers, no logic duplicated

All human-JWT authenticated via humanAuthMiddleware; non-member gets 404, non-owner gets 403 on owner-only routes (no enumeration).

Deferred (documented, not built): org slug (needs a migration/uniqueness decision), leaving an org, ownership transfer, role changes, email change.

Test plan

  • gofmt/go vet/go build clean
  • Full go test ./... and go test -race ./... clean against real Postgres+Redis
  • TestRemoveTenantMemberConcurrentMutualRemovalKeepsAnOwner stress-tested 15x with -race, stable
  • OpenAPI documented and TestOpenAPISpecParses/TestOpenAPIRoutesMatchRuntime pass
  • Docker rebuild + boot smoke clean

Summary by CodeRabbit

  • New Features
    • Added dashboard tools for viewing and updating your profile and organization, managing members and pending invitations, and viewing organization analytics.
    • Organization access is limited to members, with owner-only controls for restricted actions.
  • Bug Fixes
    • Prevented removing yourself or the last organization owner.

…s, invites, org analytics

Human-JWT routes for the future dashboard frontend. Non-members get 404,
non-owners 403 on owner-only routes. Member removal is serialized by the
tenant row lock so an org can never lose its last owner. Org analytics
reuse the API-key analytics handlers. DEC-228..230.
@coderabbitai

coderabbitai Bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 6f127c6d-a71d-4d48-bfcc-b5dbf32a65d0

📥 Commits

Reviewing files that changed from the base of the PR and between 357ab4f and 5869fbf.

📒 Files selected for processing (11)
  • .ilana/architecture.md
  • .ilana/decisions.md
  • .ilana/ledger.md
  • .ilana/milestones.md
  • .ilana/state.json
  • internal/api/dashboard_handler.go
  • internal/api/dashboard_handler_test.go
  • internal/api/openapi.go
  • internal/api/routes.go
  • internal/database/dashboard.go
  • internal/database/dashboard_test.go

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

Adds human-authenticated dashboard routes for profile and organization management, member and invitation operations, and organization-scoped analytics. Adds database operations, API contracts, and tests for these routes.

Changes

Dashboard backend

Layer / File(s) Summary
Dashboard persistence and membership rules
internal/database/dashboard.go, internal/database/dashboard_test.go
Adds profile and organization updates, member and invitation queries, and transactional member removal that checks ownership and prevents removal of the last owner. Database tests cover these operations, including concurrent owner removal.
Profile and organization routes
internal/api/dashboard_handler.go, internal/api/routes.go, internal/api/openapi.go, internal/api/dashboard_handler_test.go, .ilana/architecture.md, .ilana/decisions.md, .ilana/ledger.md, .ilana/milestones.md, .ilana/state.json
Registers human-authenticated routes for profiles, organization details, members, and invitations. Handlers enforce membership and ownership rules, validate profile and organization updates, and map database outcomes to API responses. OpenAPI, tests, and project records describe the routes and their behavior.
Organization-scoped analytics
internal/api/dashboard_handler.go, internal/api/routes.go, internal/api/openapi.go, internal/api/dashboard_handler_test.go
Checks organization membership, adds the tenant ID to the request context, and delegates analytics requests to the existing overview and timeseries handlers. Adds API documentation and tests for member access and range validation.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant DashboardClient
  participant newMux
  participant orgAnalytics
  participant DB
  participant analyticsHandler
  DashboardClient->>newMux: Send human-authenticated analytics request
  newMux->>orgAnalytics: Route organization analytics request
  orgAnalytics->>DB: Check organization membership
  orgAnalytics->>analyticsHandler: Delegate with tenant ID in request context
  analyticsHandler-->>DashboardClient: Return analytics response
Loading

Merge Risk: ⚪ Minimal · up to 5869f

The dashboard routes have no established merge-blocking issue and are mergeable after normal checks.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 5869f

The new endpoints enforce human authentication and organization access, and member removal has a concurrency safeguard. However, two owner-only updates can complete after the caller loses ownership because authorization is checked before, rather than as part of, the update. The exposure is limited to an organization the caller previously owned.

Retained concerns

  • Medium · security · inferred: New organization-settings and invitation-revocation writes do not revalidate owner authority at the mutation boundary. An owner removed after the request's access check can still complete either write.
Security review details

Security Blast Radius

  • inferred — The identified stale-authority window requires a valid human token and prior ownership; the affected writes are constrained to the requested organization, rather than granting cross-organization access.

Security Findings and Attack Paths

  • inferred — If another owner removes the caller after orgAccess approves a PATCH or invitation DELETE but before its database statement, the statement can still change settings or revoke a pending invitation. The member-removal path has an in-transaction ownership recheck that these two paths lack.

Trust Boundaries and Controls

  • observed — Every new dashboard route is registered behind human JWT authentication. Organization access uses the verified human ID and route organization ID; analytics receives tenant context only after membership validation.

Resilience and Maintainability Implications

  • observed — Invitation revocation uses a tenant-scoped statement, and repeated revocation leaves an existing inactive invitation unchanged. The supplied tests do not establish its behavior under concurrent ownership loss.

Hardening Proposals

  • proposed — Couple owner authorization to organization-settings and invitation-revocation mutations, using an owner recheck with appropriate transaction ordering, and exercise concurrent owner removal against both operations.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 6 files. (5 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding the dashboard backend for v0.47 phase 3a.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 11.11% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 18 functions across 6 files. (5 skipped: 5 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@Ferousco-dev
Ferousco-dev merged commit 5d079c8 into main Sep 25, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant