Skip to content

Commit 6e33520

Browse files
authored
Merge pull request #1 from NodeDB-Lab/ui/skeletons
NodeDB-Studio UI skeleton
2 parents 6eeba27 + c6340de commit 6e33520

85 files changed

Lines changed: 13848 additions & 44 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
/nodedb-data/
77
**/*.rs.bk
88
*.pdb
9-
Cargo.lock
109

1110
# IDE and Editor files
1211
.vscode/
@@ -34,8 +33,6 @@ Cargo.lock
3433
.env.*.local
3534
.envrc
3635
resource
37-
AGENTS.md
38-
CLAUDE.md
3936
.codex
4037

4138
# OS-specific
@@ -102,3 +99,9 @@ dmypy.json
10299
.gradle/
103100

104101
.cargo/
102+
103+
# Local reference only — not tracked
104+
docs/nodedb_lab_studio_mockup_v4.html
105+
specs/*
106+
docs/*
107+
.DS_Store

AGENTS.md

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
# AGENTS.md
2+
3+
Contributor & AI-agent guide for **NodeDB Studio**. This is the single source of
4+
truth for setup, commands, and conventions. (`CLAUDE.md` imports this file;
5+
Cursor, Codex, Copilot, Gemini CLI, etc. read it directly.)
6+
7+
Keep this file accurate — if you change build/test commands or conventions,
8+
update it in the same PR.
9+
10+
## What this is
11+
12+
NodeDB Studio is a **desktop GUI client for NodeDB**, built in Rust with
13+
**Dioxus** (desktop). It is a separate repo from the NodeDB server.
14+
15+
- **Rust**: edition 2024, MSRV pinned in `Cargo.toml` (`rust-version`, currently 1.96).
16+
- **UI**: Dioxus **0.7** with the `desktop` + `router` features.
17+
- **Backend seam**: `nodedb-client` / `nodedb-types` (the typed Rust client).
18+
Today the app runs on hardcoded mock data behind a `ConnectionService` trait;
19+
the real client-backed impl plugs in at that seam.
20+
- **Serialization**: `sonic_rs` for any runtime JSON (display), `serde` derive on
21+
models. The wire format to the server is the client's concern (MessagePack).
22+
23+
This is a Cargo workspace; the app is the `nodedb-studio` member crate.
24+
25+
## Setup — local NodeDB dependency (do this first)
26+
27+
`Cargo.toml` pins `nodedb-client` / `nodedb-types` to a published version, but
28+
those crates are not on crates.io yet. Point them at a local NodeDB checkout with
29+
a **gitignored** Cargo patch — never hardcode machine paths in `Cargo.toml`.
30+
31+
Create `.cargo/config.toml` at the workspace root (already gitignored):
32+
33+
```toml
34+
[patch.crates-io]
35+
nodedb-client = { path = "../nodedb/nodedb-client" }
36+
nodedb-types = { path = "../nodedb/nodedb-types" }
37+
```
38+
39+
Adjust the paths to your checkout. The version pinned in `Cargo.toml` must match
40+
your local NodeDB workspace version (see its root `Cargo.toml`). If Cargo says
41+
your toolchain is too old, run `rustup update stable`.
42+
43+
## Commands
44+
45+
```bash
46+
cargo run -p nodedb-studio # launch the desktop app (1440x900 window)
47+
dx serve # optional: run with hot-reload (needs `dioxus-cli`)
48+
cargo build --release # release binary at target/release/nodedb-studio
49+
50+
cargo fmt --all # format (CI gate runs `--check`; just run the plain form)
51+
cargo clippy --workspace --all-targets --all-features -- -D warnings # lints (warnings block merge)
52+
cargo nextest run # tests (use nextest, not `cargo test`)
53+
cargo nextest run -E 'test(my_test_name)' # one test by name
54+
```
55+
56+
Install the test runner once with `cargo install cargo-nextest --locked`.
57+
There are no doctests today (the crate is a binary, no lib target), so
58+
`cargo test --doc` is not part of the gate; add it if a library crate is introduced.
59+
60+
## Verify a change is done
61+
62+
Run these locally before pushing — they mirror CI and must all pass:
63+
64+
```bash
65+
cargo fmt --all
66+
cargo clippy --workspace --all-targets --all-features -- -D warnings
67+
cargo nextest run
68+
```
69+
70+
For UI changes, also `cargo run -p nodedb-studio` and confirm the screen renders.
71+
72+
## Project structure
73+
74+
```
75+
nodedb-studio/src/
76+
main.rs desktop launch + window config (Config / WindowBuilder)
77+
app.rs root App: context providers + connected/disconnected state machine
78+
routes.rs Route enum + StudioLayout (persistent chrome + Outlet)
79+
components/ reusable chrome (rail, topbar, statusbar, modal, popovers, …)
80+
views/ one module per routed screen (explorer, admin, streams, …)
81+
modals/ modal bodies + the ModalHost
82+
state/ live UI state as Dioxus signals (connection, prefs, ui, …)
83+
models/ typed domain data (collection, notification, …)
84+
services/ ConnectionService trait — the backend seam (mock impl today)
85+
data/mock.rs ALL hardcoded mock data, in one place
86+
assets/styles.css CSS ported from the design (loaded via asset!)
87+
```
88+
89+
## Code style & conventions
90+
91+
### Rust
92+
93+
- **No `.unwrap()` / `.expect()` / `panic!` in non-test code.** Use typed
94+
`thiserror` errors and propagate with `?`. Never `Result<T, String>`.
95+
- **Module roots (`mod.rs`) contain only `pub mod` / `pub use`** — no logic, no
96+
type definitions. Put the module's code in a sibling file (e.g. `view.rs`).
97+
- **Files stay under 500 lines** of non-test code — split by concern first.
98+
- Use **`nodedb_types::Value`** for values that come from / go to the database.
99+
- **`sonic_rs` for runtime JSON**, never `serde_json`. Carry data as native typed
100+
values; serialize to JSON only at the view boundary, for display.
101+
- Naming: `UpperCamelCase` types, `snake_case` fns/modules. No `get_` prefix.
102+
- Do **not** write `_ =>` catch-alls on exhaustive domain enums — let the compiler
103+
flag every site that needs updating.
104+
105+
### Dioxus 0.7
106+
107+
- Components are `PascalCase` `#[component]` functions returning `Element`.
108+
- **State**: `use_signal` (signals are `Copy`). Subscribe with `.read()`; use
109+
**`.peek()`** in event handlers and when reading + writing the same signal.
110+
**Never hold a `.read()`/`.write()` guard across an `.await`.** Prefer
111+
`use_context`/`provide_context` over global statics.
112+
- **Lists need stable keys** (`key: "{item.id}"`) — never the array index.
113+
- Use inline format strings in attributes/text (`"{value}"`); avoid redundant
114+
closures over existing handlers.
115+
- **Forms submit by default in 0.7** — call `e.prevent_default()` in `onsubmit`.
116+
- **Never block the main thread.** CPU work → `std::thread::spawn`; async IO →
117+
`spawn` / `use_resource` / `use_action`; long-lived tasks → `spawn_forever`.
118+
Write results back into a signal.
119+
- Keep business/state logic in plain Rust (`state/`, `services/`, `data/`) so it
120+
is testable without a renderer.
121+
122+
## Testing
123+
124+
- **Unit tests** inline: `#[cfg(test)] mod tests { … }` (can reach private items).
125+
- **Integration tests** in `tests/`, public API only; shared helpers in
126+
`tests/common/mod.rs` (not `tests/common.rs`).
127+
- Render-level checks: `dioxus_ssr::render_element(...)` to assert on output
128+
without a window.
129+
130+
## Git, commits & PRs
131+
132+
- **Conventional Commits**: `feat|fix|perf|refactor|test|docs|chore(scope): summary`.
133+
One logical change per commit.
134+
- Branch from `main`; keep PRs small and focused (open an issue first for large
135+
changes). A PR must pass fmt, clippy, and nextest before review.
136+
137+
## Boundaries
138+
139+
**Always**
140+
- Run fmt + clippy + nextest before pushing.
141+
- Keep machine-specific paths in the gitignored `.cargo/config.toml`, not in `Cargo.toml`.
142+
143+
**Ask first**
144+
- Adding a new dependency, or bumping the Dioxus / Rust version.
145+
- Adding a new top-level module or changing the `ConnectionService` seam.
146+
147+
**Never**
148+
- Commit secrets, credentials, or `.cargo/config.toml`.
149+
- Use `.unwrap()`/`.expect()`/`panic!` in non-test code, or `serde_json` for JSON.
150+
- Submit AI-generated code you have not read and understood.

CLAUDE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# CLAUDE.md
2+
3+
@AGENTS.md

0 commit comments

Comments
 (0)