Skip to content

feat(ui): improve user dropdown, profile page, and org selector - #5089

Open
itzzjustmateo wants to merge 14 commits into
Dokploy:canaryfrom
itzzjustmateo:feat/ui-dev-env-improvements
Open

feat(ui): improve user dropdown, profile page, and org selector#5089
itzzjustmateo wants to merge 14 commits into
Dokploy:canaryfrom
itzzjustmateo:feat/ui-dev-env-improvements

Conversation

@itzzjustmateo

@itzzjustmateo itzzjustmateo commented Aug 15, 2026

Copy link
Copy Markdown

Summary

  • User dropdown: show the account name with a role badge, add icons to every action, and a red hover state on "Sign out".
  • Organization selector dialog: more compact layout (narrower popover, smaller row action buttons, tighter spacing).
  • Profile page: redesigned into sectioned layout (Profile Information / Security), added live avatar preview and an on-demand "Change Password" toggle with validation.
  • Avatar: new shared AvatarPicker (no avatar, preset, gradient, solid color, custom URL, and local image upload with preview) and clip images to the rounded border.
  • Organization logo: new OrganizationLogoInput so organization logos can be uploaded directly instead of pasting an external URL; the logo is applied when an organization is created at registration.
  • Register page: set the organization name and logo during signup.
  • Postgres 18 setup: mount the data volume at /var/lib/postgresql (postgres:18+ refuses the old /var/lib/postgresql/data subpath) and only expose the dev database on 127.0.0.1; includes a docker-compose.dev.yml for local Postgres.
  • Dev database: just dev now starts the local Postgres (just db) and applies migrations automatically before the server boots. Migration failures now halt startup instead of silently running the server against an incomplete schema (fixes runtime errors like Failed query: ... from "member" where role = $1 on a fresh/unmigrated dev DB). Added just db, just db-down, and just db-reset recipes.
  • pnpm 10: migrate overrides/peerDependencyRules/onlyBuiltDependencies from the ignored pnpm key in package.json to pnpm-workspace.yaml.
  • Dev tooling: add mise.toml (Node 24 / pnpm 10) and a justfile.

Related Issues

Testing

  • pnpm typecheck passes across all workspaces.
  • Biome lint + format clean on changed files.
  • Full test suite passes (868 passed, 5 failed — the 5 failures are Docker/network integration tests that require a running Docker daemon; unrelated to these changes).

Greptile Summary

The PR redesigns account and organization UI, adds avatar and logo upload controls, improves local development tooling, and updates the bundled PostgreSQL setup.

  • Adds sectioned profile and navigation layouts with shared avatar/logo pickers.
  • Extends registration to collect organization identity details.
  • Adds Compose/just/mise development tooling and fail-fast migration startup.
  • Moves the bundled database to PostgreSQL 18 and changes its volume and port configuration.

Confidence Score: 2/5

The PR is not safe to merge until the PostgreSQL 16 upgrade preserves existing clusters and the development Swarm database is genuinely restricted to loopback.

Existing installations are still switched directly to PostgreSQL 18 without a major-version cluster migration, while the volume remount makes the old cluster inaccessible; separately, the Swarm setup relies on an unsupported HostIp port field and therefore leaves the known database credential network-reachable.

Files Needing Attention: packages/server/src/setup/postgres-setup.ts

Security Review

The development Swarm database remains network-reachable because Docker Swarm service ports do not honor the added HostIp field; the repository-known fallback password therefore remains exposed on that path.

How this was verified: The changed service publishes port 5432 in Swarm host mode through EndpointSpec.Ports, whose PortConfig has no host-address binding field, while the code retains the known fallback password.

Reviews (3): Last reviewed commit: "fix(dev): wait for Postgres readiness an..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Context used:

@dosubot dosubot Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files. label Aug 15, 2026
@itzzjustmateo itzzjustmateo changed the title UI & dev environment improvements feat(ui): improve user dropdown, profile page, and org selector Aug 15, 2026
import { pullImage } from "../utils/docker/utils";
export const initializePostgres = async () => {
const imageName = "postgres:16";
const imageName = "postgres:18";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 PostgreSQL upgrade abandons existing data

When setup runs on an existing installation with PostgreSQL 16 data at /var/lib/postgresql/data, it updates the service to PostgreSQL 18 while reusing the volume at a new mount layout without upgrading the cluster, causing the application to connect to a new database location while existing users, projects, services, and settings remain inaccessible.

Knowledge Base Used: Server Setup and Packaging

Comment thread docker-compose.dev.yml Outdated
Comment on lines +10 to +11
ports:
- "5432:5432"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Known credential exposed to network

If the development host's port 5432 is reachable by another network peer, 5432:5432 exposes PostgreSQL on every host interface and the repository-known dokploy password lets that peer read, modify, or delete development data.

How this was verified: The Compose service publishes port 5432 without a loopback address and configures the database with the password committed in the same file.

Suggested change
ports:
- "5432:5432"
ports:
- "127.0.0.1:5432:5432"

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2335c4e97e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// postgres:18+ images store data under /var/lib/postgresql/<version>
// and refuse to start when a mount is pinned to the old
// /var/lib/postgresql/data subpath. Mount the parent instead.
Target: "/var/lib/postgresql",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the existing Postgres volume layout

When setup is rerun on an installation that already has the dokploy-postgres volume from the previous service, this changes the same named volume from being mounted at /var/lib/postgresql/data to /var/lib/postgresql while also starting postgres:18. The existing cluster files are at the volume root from the old mount, so the new image will not see them at its expected PGDATA path and can initialize/use a fresh empty cluster instead of the existing Dokploy database; a major-version upgrade also needs an explicit migration path rather than just swapping the image and mount target.

Useful? React with 👍 / 👎.

Comment on lines +50 to +51
const wantsPasswordChange = Boolean(data.password || data.currentPassword);
if (!wantsPasswordChange) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear hidden password fields before validation

If a user enables Change Password, types only one password field or a short new password, then disables the switch to save unrelated profile changes, React Hook Form keeps those unmounted field values and this refinement still treats them as a password-change attempt. The submit is then blocked by errors for fields that are no longer visible, even though onSubmit would omit passwords when changePassword is false; clear the password fields when disabling the switch or gate this validation on the toggle state.

Useful? React with 👍 / 👎.

},
{
keepValues: true,
keepValues: false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve unsaved profile edits on refetch

With keepValues changed to false, any api.user.get refetch while the user is editing this form resets all fields back to the server values. In common cases such as returning to the tab/window or another component invalidating/refetching the user query, partially edited names, email, avatar, or password fields are silently discarded before submit; keep the current form values during data refreshes or only reset on the initial load.

Useful? React with 👍 / 👎.

@itzzjustmateo
itzzjustmateo marked this pull request as draft August 15, 2026 11:25
@itzzjustmateo

Copy link
Copy Markdown
Author

almost finished

@itzzjustmateo

Copy link
Copy Markdown
Author

I am currently fixing the issues Greptile and Codex gave me :P

…gnup

Adds a shared AvatarPicker (no avatar, presets, gradients, solid colors, custom URL, and local image upload with preview) and an OrganizationLogoInput for direct logo uploads. The register/onboarding form now collects the organization name and logo, and the signup after-hook applies them to the new organization.
…migration errors

The dev server previously booted against an unmigrated or partially-migrated
database, surfacing confusing runtime errors such as 'Failed query: ...
from member where role = $1' (see Dokploy#3890).

- Run migrations automatically via a predev hook (mirrors the production start script).
- Exit non-zero when migrations fail so the server never runs against an incomplete schema.
- Add just db / db-down / db-reset recipes and start the compose Postgres from 'just dev'.
- Bind the dev Postgres to 127.0.0.1 and align .env.example with docker-compose.dev.yml.
@itzzjustmateo

Copy link
Copy Markdown
Author

to the relations: some may not be correct

When migrations fail, print recovery steps (just db-reset for local dev, restart the service for production) instead of a bare error, and keep refusing to start against an incomplete schema.
just dev previously failed with a bare 'permission denied while trying to connect to the docker API at unix:///var/run/docker.sock'. The db recipes now check Docker access first and print the exact remediation (usermod -aG docker) or tell the user to start the daemon.
just db failed with 'Bind for 0.0.0.0:5432 failed: port is already allocated' when a leftover Swarm dokploy-postgres service (from dokploy:setup) occupies 5432. The new scripts/dev-db.sh runs docker compose and, on failure, identifies what holds port 5432 (swarm service, container, or host process) and prints the exact remediation (docker service rm dokploy-postgres, stop the container, or use a custom DATABASE_URL).
predev now runs wait-for-postgres before migrating, so a fresh compose DB (which takes a few seconds to initdb) no longer fails with ECONNREFUSED. scripts/dev-db.sh also waits for the container healthcheck to pass before returning.

pnpm: finish the v10 config migration by moving the remaining overrides (esbuild, better-call, @better-fetch/fetch, @types/react, @types/react-dom) from the package.json 'pnpm'/'resolutions' keys into pnpm-workspace.yaml. The 'pnpm' key was already ignored by pnpm 10 (emitting a warning on every run), and 'resolutions' silently suppressed the workspace overrides; the lockfile is unchanged apart from the recorded override set ordering.

dev: add a dev-only BETTER_AUTH_SECRET to .env.example so better-auth no longer falls back to the hardcoded insecure default during development.
@itzzjustmateo

Copy link
Copy Markdown
Author

before it worked, now I cannot test because I fcked up my docker configs

@itzzjustmateo
itzzjustmateo marked this pull request as ready for review August 15, 2026 13:37
Comment on lines +61 to +64
// Only expose the dev database on localhost so the known
// legacy credential is never reachable from the network.
HostIp: "127.0.0.1",
} as PortConfig,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Loopback restriction is ignored

When a development setup creates or updates this Swarm service, HostIp is not supported on a Swarm PortConfig, so host-mode port 5432 remains exposed through the host's network interfaces while the service retains the repository-known fallback password.

How this was verified: The service publishes port 5432 through Swarm EndpointSpec.Ports, whose PortConfig has no host-address binding field.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 52f081ae44

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

},
// Only expose the dev database on localhost so the known
// legacy credential is never reachable from the network.
HostIp: "127.0.0.1",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not rely on unsupported HostIp for Swarm

When NODE_ENV=development runs dokploy:setup, this still creates/updates a Swarm service publishing 5432; Docker’s service publish docs only support published, target, mode, and protocol, and Swarm’s routing docs state published ports listen on any IP assigned to the node. HostIp is therefore not honored for this service port, so the dev Postgres instance can remain reachable off-host despite the known fallback credential; use the Compose dev DB, avoid publishing the port, or add an explicit firewall rule instead.

Useful? React with 👍 / 👎.

Comment on lines +10 to +11
const POSTGRES_PASSWORD =
process.env.POSTGRES_PASSWORD ?? LEGACY_POSTGRES_PASSWORD;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align POSTGRES_PASSWORD with the app database URL

When setup is run with only POSTGRES_PASSWORD set and no DATABASE_URL/POSTGRES_PASSWORD_FILE, this initializes or updates the Postgres service with the custom password, but packages/server/src/db/constants.ts still builds the fallback dbUrl from the legacy hard-coded password. The migration that runs immediately after setup and later app startups will then authenticate with the wrong credential; either derive the fallback URL from POSTGRES_PASSWORD too or require DATABASE_URL whenever this env is honored.

Useful? React with 👍 / 👎.

Comment thread justfile
# Install dependencies + set up the local dev environment
setup:
pnpm install
pnpm run dokploy:setup

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid setting up the Swarm DB in the dev recipe

If a contributor follows the new just setup recipe and then runs just dev, this line runs dokploy:setup, which creates the Swarm dokploy-postgres service on port 5432; just dev then starts the Compose database and scripts/dev-db.sh explicitly treats that Swarm service as a leftover conflict that must be removed manually. The advertised setup path therefore breaks the next dev command, so this recipe should use the Compose dev DB path instead of dokploy:setup (or otherwise avoid creating the conflicting Swarm service).

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant